from typing import List, Optional, Union
from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect, WebSocketException
from pydantic import BaseModel
from core import Vue2BlueConverter, gen_project_description

class ErrorFeedback(BaseModel):
    component: str
    message: str
    code: str


class Message(BaseModel):
    """
    Message:
    type:
        xxx:xxx

        convert:start  开始转换
        convert:step  当前转换步骤
        convert:result  当前转换结果
        convert:feedback  转换结果反馈
        convert:done  转换结束

        xxx:xxx
    """

    type: str
    filepath: Optional[str] = ""
    content: str
    error: Optional[List[ErrorFeedback]] = ""
    process: Optional[str] = ""
    extra: Optional[dict] = {}

app = FastAPI()

@app.post("/description")
async def get_description(request: Request):
    data = await request.json()
    res = gen_project_description(data["projectName"], data["description"])
    return res

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    converter = None
    try:
        while True:
            message = await websocket.receive_json()
            message = Message(**message)
            if (message.type == "convert:start"):
                converter = Vue2BlueConverter(message.content)
                pages = message.extra.get("pages", [])
                converter.set_global_memory("pages", pages)
                converter.set_global_memory("filepath", message.filepath)
                for result in converter.start():
                    # 这里可以选择不发送转换过程中的结果
                    if result.get("start", True):
                        await websocket.send_json(
                            Message(type="convert:step", content=result["content"], process=result["process"]).model_dump()
                        )
                    else:
                        await websocket.send_json(
                            Message(type="convert:result", content=result["content"], process=result["process"]).model_dump()
                        )
                await websocket.send_json(
                    Message(type="convert:result", content=result["content"], process="done").model_dump()
                )
            elif (message.type == "convert:feedback"):
                content = converter.error_feedback(message.error)
                await websocket.send_json(
                    Message(type="convert:result", content=content, process="done").model_dump()
                )
            elif (message.type == "convert:done"):
                break
            # await websocket.send_json(f"Message text was: {message}")
    except StopIteration:
        await websocket.send_json(Message(type="convert:done", content="", process="done").model_dump())
    except WebSocketDisconnect:
        print("WebSocketDisconnect")
        if converter:
            converter.stop()
    except WebSocketException:
        print("WebSocketException")
        if converter:
            converter.stop()